package com.suncky.frame.base.dialog;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.StyleRes;
import androidx.viewbinding.ViewBinding;

import com.suncky.frame.R;

public abstract class BaseDialogWrapper<B extends ViewBinding, T> {

    protected final Context context;
    protected Dialog dialog;
    protected B binding;
    protected int styleResID = 0;
    protected int layoutResID = 0;
    protected int width = 0;
    protected int height = 0;
    protected int maxHeight = 0;
    protected int gravity = Gravity.BOTTOM;
    protected int windowAnimationRes = R.style.bottom_window_animation;
    protected @DrawableRes int backgroundResource = R.color.black;
    protected boolean cancelable = true;
    protected Callback<T> callback;

    private boolean isCreated = false;
    private boolean isAttached = false;
    private boolean isDetached = false;

    public BaseDialogWrapper(Context context, int layoutResID) {
        this(context, R.style.custom_dialog_style, layoutResID, null);
    }

    public BaseDialogWrapper(Context context, int styleResID, int layoutResID) {
        this(context, styleResID, layoutResID, null);
    }

    public BaseDialogWrapper(Context context, int layoutResID, Callback<T> callback) {
        this(context, R.style.custom_dialog_style, layoutResID, callback);
    }

    public BaseDialogWrapper(Context context, int styleResID, int layoutResID, Callback<T> callback) {
        this.context = context;
        this.styleResID = styleResID;
        this.layoutResID = layoutResID;
        this.callback = callback;
        initDialog(context, styleResID, layoutResID);
    }

    private void initDialog(Context context, int styleResID, int layoutResID) {
        dialog = new Dialog(context,styleResID){
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                BaseDialogWrapper.this.onCreate(savedInstanceState);
                customizeDialog(this);
                initView();
                initData();
                isCreated = true;
            }

            @Override
            protected void onStart() {
                super.onStart();
                BaseDialogWrapper.this.onStart();
            }

            @Override
            protected void onStop() {
                super.onStop();
                BaseDialogWrapper.this.onStop();
            }

            @Override
            public void onAttachedToWindow() {
                super.onAttachedToWindow();
                BaseDialogWrapper.this.onAttachedToWindow();
                isAttached = true;
            }

            @Override
            public void onDetachedFromWindow() {
                super.onDetachedFromWindow();
                BaseDialogWrapper.this.onDetachedFromWindow();
                isDetached = true;
            }

        };
        View view = dialog.getLayoutInflater().inflate(layoutResID, null);
        binding = onCreateBinding(view);
        dialog.setContentView(view);
    }

    protected void initView() {

    }

    protected void initData() {

    }

    protected void onCreate(Bundle savedInstanceState) {

    }

    protected void onStart() {
    }

    protected void onStop() {
    }

    public void onAttachedToWindow() {
    }
    public void onDetachedFromWindow() {
    }

    public abstract B onCreateBinding(@NonNull View contentView);

    /**
     * 可对dialog进行个性化设置
     * @param dialog
     */
    public void customizeDialog(Dialog dialog) {
        dialog.setCanceledOnTouchOutside(cancelable);
        dialog.setCancelable(cancelable);
        Window window = dialog.getWindow();
        if (window != null) {
            window.setGravity(gravity);
            window.setWindowAnimations(windowAnimationRes);
            window.setBackgroundDrawableResource(backgroundResource);
            int winWidth = width != 0 ? width : WindowManager.LayoutParams.MATCH_PARENT;
            int winHeight = height != 0 ? height : WindowManager.LayoutParams.WRAP_CONTENT;
            window.setLayout(winWidth, winHeight);
            if (maxHeight > 0) {
                //限制弹框内容的最大高度
                window.findViewById(android.R.id.content).addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                    @Override
                    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                        if (bottom - top > maxHeight) {
                            v.getLayoutParams().height = maxHeight;
                            v.requestLayout();
                            window.setLayout(winWidth, maxHeight);
                        }
                    }
                });
            }

        }
    }

    public Context getContext() {
        return context;
    }

    public Dialog getDialog() {
        return dialog;
    }

    public B getBinding() {
        return binding;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public void setMinHeight(int minHeight) {
        getBinding().getRoot().setMinimumHeight(minHeight);
    }

    public void setMaxHeight(int maxHeight) {
        this.maxHeight = maxHeight;
    }

    public void setGravity(int gravity) {
        this.gravity = gravity;
    }

    public void setWindowAnimationRes(@StyleRes int windowAnimationRes) {
        this.windowAnimationRes = windowAnimationRes;
    }

    public void setBackgroundResource(@DrawableRes int backgroundResource) {
        this.backgroundResource = backgroundResource;
    }

    public void setCancelable(boolean cancelable) {
        this.cancelable = cancelable;
    }

    public void setCallback(Callback<T> callback) {
        this.callback = callback;
    }

    public void show(){
        if (dialog == null) {
            return;
        }
//        customizeDialog(dialog);
        if (!dialog.isShowing()) {
            dialog.show();
        }
    }

    public void dismiss(){
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
    }

    public boolean isShowing(){
        return dialog != null && dialog.isShowing();
    }

    public boolean isCreated() {
        return isCreated;
    }

    public boolean isAttached() {
        return isAttached;
    }

    public boolean isDetached() {
        return isDetached;
    }

    public interface Callback<T>{
        void onResult(T o, BaseDialogWrapper<? extends ViewBinding, T> dialog, Object... extras);
    }
}
